/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: mutex lock
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2021-11-13     JasonHu           Init
 * 2022-03-18     JasonHu           Add MutexTryLock
 * 2023-01-15     JasonHu           Add wait list
 */

#ifndef __SCHED_MUTEX___
#define __SCHED_MUTEX___

#include <nxos_mini.h>
#include <base/spin.h>
#include <base/list.h>
#include <base/clock.h>
#include <base/sched.h>

struct NX_Mutex
{
    NX_U32 magic;  /* magic for mutex init */
    NX_Spin lock;  /* lock for mutex value */
    NX_Spin waitLock;  /* wait lock */
    NX_List waitList;  /* wait list */
#ifdef NX_SCHED_REALTIME
    NX_U32 originalPriority;    /* mutex thread original priority */
    void *holder;
#endif
};
typedef struct NX_Mutex NX_Mutex;

#define NX_MUTEX_UNLOCK_OK(mutex) (NX_SPIN_UNLOCK_OK(&(mutex)->lock))

NX_Error NX_MutexInit(NX_Mutex *mutex);
NX_Error NX_MutexInitLocked(NX_Mutex *mutex);
NX_Error NX_MutexLock(NX_Mutex *mutex);
NX_Error NX_MutexTryLock(NX_Mutex *mutex);
NX_Error NX_MutexLockTimeout(NX_Mutex *mutex, NX_TimeVal ms);
NX_Error NX_MutexUnlock(NX_Mutex *mutex);
NX_Bool NX_MutexIsLocked(NX_Mutex *mutex);

#define NX_MutexLockTimeoutTicks(sem, ticks) NX_MutexLockTimeout(sem, NX_ClockTickToMillisecond(ticks))

#endif /* __SCHED_MUTEX___ */
